<template>
    <div class="list-body" ref="listbody" v-loading="listLoading">
        <el-page-header>
            <template #content>
                <span> {{ route.name }} </span>
            </template>
            <template #extra>
                <el-button type="primary" :icon="Refresh" @click="openSearch">筛选</el-button>
                <el-button type="primary" :icon="Refresh" @click="resetList">刷新</el-button>
                <el-button type="primary" :icon="Plus" @click="addClick">新增</el-button>
            </template>
            <div>
                <div class="searchBox" ref="searchBox">
                    <div class="searchItems">
                        <el-row>
                            <el-col v-for="(searchItem, index) in searchItemArr" :key="index" :span="6" class="searchItem">
                                <label :for="searchItem.key">{{searchItem.title}}</label>
                                <el-input :id="searchItem.key" v-if="searchItem.type == 'input'" style="width: 100%" v-model="where[searchItem.dataKey]" :placeholder="searchItem.placeholder ? searchItem.placeholder : '请输入'" />
                                <el-switch v-else-if="searchItem.type === 'switch'" :active-value="searchItem.switchOpen"
                                    :inactive-value="searchItem.switchClose" v-model="where[searchItem.dataKey]"
                                    :active-color="searchItem.switchOpenColor" :inactive-color="searchItem.switchCloseColor"
                                    :active-text="searchItem.switchOpenText" :inactive-text="searchItem.switchCloseText"/>
                                <el-select-v2
                                    v-else-if="searchItem.type === 'select'"
                                    v-model="where[searchItem.dataKey]"
                                    :options="searchItem.selectOption"
                                    :placeholder="searchItem.placeholder ? searchItem.placeholder : '请选择'"
                                />
                                <el-date-picker
                                    v-else-if="searchItem.type === 'datetime'"
                                    v-model="where[searchItem.dataKey]"
                                    type="datetimerange"
                                    range-separator="到"
                                    :start-placeholder="searchItem.startDatePlace"
                                    :end-placeholder="searchItem.endtDatePlace"
                                />
                                <span v-else>暂不支持其他组件</span>
                                <el-divider direction="vertical" style="height:auto" />
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="8" :offset="8">
                                <el-button type="primary" @click="resetSearch">重置</el-button>
                                <el-button type="primary" @click="closeSearch">确定</el-button>
                            </el-col>
                        </el-row>
                    </div>
                    <el-divider />
                </div>
                <el-table-v2 :columns="columns" :data="data" :width="tableWidth" :height="tableHeight">
                    <template #footer>
                        <el-pagination
                                v-model:current-page="tablePage"
                                v-model:page-size="tableSize"
                                :page-sizes="[10, 20, 50, 100, 200, 500]"
                                :background="false"
                                layout="prev, pager, next,sizes, total"
                                :total="sum"
                                @size-change="handleSizeChange"
                                @current-change="handleCurrentChange"
                        />
                    </template>
                </el-table-v2>
            </div>
        </el-page-header>
        <el-dialog v-model="isEditting" :title="editTitle" :width="edit_width" :before-close="beforCloseEdit">
            <EditForm v-if="isEditting" :new="newData" :model="model" :form-data="editData" @closeForm="beforCloseEdit"/>
        </el-dialog>
        
        <el-dialog v-model="isAuthing" :title="authTitle" :width="edit_width" :before-close="beforCloseAuth">
            <AuthForm v-if="isAuthing" :model="model" :id="authId" @closeForm="beforCloseAuth"/>
        </el-dialog>
    </div>
</template>

<script lang="tsx" setup>
import {ref, onMounted, reactive} from "vue"
import {useRoute} from "vue-router"
import type {FunctionalComponent} from "vue"
import {Delete, Edit, Plus, Refresh} from "@element-plus/icons-vue"
import type {InputInstance } from "element-plus"
import {ElInput, ElNotification, ElMessage}from "element-plus"

import EditForm from "@/views/list/edit.vue"
import AuthForm from "@/views/list/auth.vue"
import {getColumn, getList, updateData, deleteData} from "@/api/resources"

type SelectionCellProps = {
    value: string
    intermediate?: boolean
    onChange: (value: string) => void
    forwardRef: (el: InputInstance) => void
    onBlur:(event: FocusEvent) => void
}

const InputCell: FunctionalComponent<SelectionCellProps> = ({value, onChange,  forwardRef, onBlur}) => {
    return <ElInput ref={forwardRef as any} onInput={onChange} modelValue={value} onBlur={onBlur}/>
}

const route = useRoute()    
const columns = ref([])     // 表头
const data = ref([])        // 表格数据
const model = route.path.split("/")[1]      // 获取当前路由的mudole
const editTitle = ref("")           // 编辑表单标题
let editData = reactive({})         // 编辑表单数据
const isEditting = ref(false)
const newData = ref(false)
const tablePage = ref(1)            // 表格页码
const tableSize = ref(10)           // 表格每页条数
const sum = ref(0)                  // 表格总条数
const searchBox = ref()             // 搜索框
const searchItemArr = ref()         // 搜索项

const where = ref()

const listbody = ref()              // 表格
const tableWidth = ref(0)           // 表格宽度
const tableHeight = ref(0)          // 表格高度
const listLoading = ref(true)       // 表格加载中
const edit_width = ref('50%')       // 编辑框宽度

const needAuth = ref(false)
const isAuthing = ref(false)
const authTitle = ref('')
const authId = ref(0)
/**
 * 重载列表
 */
function reloadList() {
    listLoading.value = true
    getList(model, where.value, tablePage.value, tableSize.value).then(({code, ext, data: remoteData, msg} :any) => {
        if (code === 1) {
            data.value = remoteData
            sum.value = ext.sum
        } else {
            ElNotification({
                title: "系统异常",
                message: msg,
                duration: 3000,
                position: "bottom-right"
            })
        }
        listLoading.value = false
    })
}

onMounted(() => {
    resetList()

    tableWidth.value = listbody.value.clientWidth - 20
    tableHeight.value = listbody.value.clientHeight - 70 - 20
})
/**
 * 改变当前分页大小发生改变时触发
 * @param size 
 */
const handleSizeChange = (size:any) => {
    tableSize.value = size

    reloadList()
}
/**
 * 改变当前分页页码发生改变时触发
 * @param page 
 */
const handleCurrentChange = (page:any) => {
    tablePage.value = page

    reloadList()
}
/**
 * 点击新增按钮事件
 */
const addClick = () => {
    editTitle.value = "新增"
    newData.value = true
    isEditting.value = true
    editData = {}
}
/**
 * 编辑框关闭事件
 */
const beforCloseEdit = () => {
    isEditting.value = false
    newData.value = false
    reloadList()
}
const beforCloseAuth = () => {
    isAuthing.value = false
    reloadList()
}
// 加载列表头
getColumn(model).then((res:any) => {
    const columnArr = res.data.columns
    if(res.ext) {
        if(res.ext.edit_width) {
            edit_width.value = res.ext.edit_width
        }
        if(res.ext.needAuth){
            console.log('needAuth', needAuth)
            needAuth.value = res.ext.needAuth
        }
    }
    columnArr.map((column:any) => {
            if (column.editable) {
                column.cellRenderer = ({rowData, column}:any) => {
                    const onChange = (value: string) => {
                        rowData[column.dataKey] = value
                    }
                    const onEnterEditMode = () => {
                        rowData.editing = true
                    }
                    const onExitEditMode = () => {
                        listLoading.value = true
                        updateData(model, rowData).then((res:any) => {
                            rowData.editing = false
                            listLoading.value = false
                        })
                    }
                    const input = ref()
                    const setRef = (el:any) => {
                        input.value = el
                        if (el) {
                            el.focus?.()
                        }
                    }

                    return rowData.editing ? (
                        // eslint-disable-next-line no-undef
                        <InputCell
                            forwardRef={setRef}
                            value={rowData[column.dataKey]}
                            onChange={onChange}
                            onBlur={onExitEditMode}
                        />
                    ) : (
                        <div class="table-v2-inline-editing-trigger" onClick={onEnterEditMode}>
                            {rowData[column.dataKey]}
                        </div>
                    )
                }
            }
            if (column.isSelect) {
                column.cellRenderer = ({rowData, column}:any) => {
                    const updateRowData = rowData
                    const onChange = (val:any) => {
                        updateRowData[column.dataKey] = val
                    }

                    const updateToRemote = () => {
                        updateData(model, updateRowData).then(({code, msg}:any) => {
                            if (code === 1) {
                                rowData[column.dataKey] = updateRowData[column.dataKey]
                            } else {
                                ElMessage({message: msg,type: 'warning'})
                            }
                        })
                    }
                    return (
                        <el-select-v2
                            key={"select" + rowData["id"]}
                            v-model={rowData[column.dataKey]}
                            filterable
                            options={column.selectOption}
                            placeholder={column.placeholder}
                            change={onChange}
                            blur={updateToRemote}
                        />
                    )
                }
            }
            if (column.isSwitch) {
                column.cellRenderer = ({rowData, column}:any) => {
                    const onChange = () => {
                        return new Promise((resolve, reject) => {
                            const updateRowData = rowData
                            updateRowData[column.dataKey] = rowData[column.dataKey] === 1 ? 0 : 1
                            updateData(model, updateRowData).then((res:any) => {
                                rowData[column.dataKey] = updateRowData[column.dataKey]
                                // console.log(rowData[column.dataKey])
                                resolve(true)
                            })
                        })
                    }
                    return (
                        <el-switch
                            key={"switch" + rowData["id"]}
                            v-model={rowData[column.dataKey]}
                            active-value={column.switchOpen}
                            inactive-value={column.switchClose}
                            before-change={onChange}
                        />
                    )
                }
            }
            if (column.isImage) {
                column.cellRenderer = ({rowData, column}:any) => {
                    return(<el-image style={"width: "+column.iWidth +"px; height: "+ column.iHeight +"px"} src={rowData[column.dataKey]} fit="cover" />)
                }
            }
            return column
        }
    )
    columnArr.push({
        cellRenderer: ({rowData, column}:any) => {
            const editClick = () => {
                editTitle.value = "编辑"
                isEditting.value = true
                editData = rowData
            }

            const deleteClick = () => {
                console.log(rowData, column)
                deleteData(model, rowData.id).then((res :any) => {
                    reloadList()
                    console.log(res)
                })
            }

            const authing = () => {
                isAuthing.value = true
                authTitle.value = (rowData.name ? rowData.name : (rowData.title ? rowData.title: ('数据' + rowData.id))) + "   审核中"
                authId.value = rowData.id
            }
            return (
                <el-button-group>
                    <el-button type="primary" icon="Edit" onClick={editClick}/>
                    <el-button type="primary" icon="Delete" onClick={deleteClick}/>
                   {needAuth.value ? <el-button v-if={needAuth.value} type="primary" icon="EditPen" onClick={authing} />:''}
                </el-button-group>
            )
        },
        dataKey: "option",
        key: "option",
        title: "操作",
        width: 150
    })
    columns.value = res.data.columns
    searchItemArr.value = res.data.searchs
    where.value = {}
    searchItemArr.value.map((item:any) => {
        where.value[item.key] = item.default
    })
    listLoading.value = false
})

/**
 * 打开搜索栏
 */
function openSearch() {
    searchBox.value.style.maxHeight = "600px"
}

/**
 * 关闭搜索栏
 */
function closeSearch() {
    reloadList()
    searchBox.value.style.maxHeight = 0
}
/**
 * 重置搜索栏
 */
function resetSearch() {
    where.value={}
    resetList()
    
    searchBox.value.style.maxHeight = 0
}

/**
 * 重置列表
 */
function resetList() {
    tablePage.value = 1
    tableSize.value = 10

    reloadList()
}
</script>

<style lang="scss" scoped>
.list-body {
    padding: 10px;
    width: 100%;
    height: 100%;
}
.searchBox{
    max-height: 0;
    background-color: white;
    transition: max-height .5s;
}
.searchItems{
    overflow: hidden;
}
.searchItem{
    margin-left: 15px;
    font-size: 15px;
    display: flex;
    justify-content: start;
    align-self: center;
    gap: 15px;
    label{
        white-space: nowrap;
        display: flex;
        align-items: center;
    }
    flex-direction: row;
    overflow: hidden;
}

.toSearch{
    display: flex;
    justify-self: center;
}
</style>
